
export default class Stream {

    private dv:DataView;
    private position:number = 0;
    private littleEndian:boolean;


    constructor(littleEndian?:boolean){
        this.littleEndian = littleEndian || false;
    }

    // ArrayBuffer转为字符串，参数为ArrayBuffer对象
    ab2str(buf) {
        return String.fromCharCode.apply(null, new Uint16Array(buf));
    }
 
    // 字符串转为ArrayBuffer对象，参数为字符串
    str2Buffer(str) {
        var buf = new ArrayBuffer(str.length*2); // 每个字符占用2个字节
        var bufView = new Uint16Array(buf);
        for (var i=0, strLen=str.length; i<strLen; i++) {
            bufView[i] = str.charCodeAt(i);
        }
        return buf;
    }    

    initWithCount(byteCount:number){
        var byteArr = new ArrayBuffer(byteCount);   
        //参数是ArrayBuffer的字节大小。
        this.dv = new DataView(byteArr);  
    }
    
    initWithStr(str:string){
        //参数是ArrayBuffer的字节大小。
        this.dv = new DataView(this.str2Buffer(str));  
    }
    setUInt8(value:number){
        this.dv.setUint8(this.position,value);
        this.position ++;
    }
    setUInt16(value:number){
        this.dv.setUint16(this.position,value, this.littleEndian);
        this.position += 2;
    }
    setUInt32(value:number){
        this.dv.setUint32(this.position,value, this.littleEndian);
        this.position += 4;
    }    

    setInt8(value:number){
        this.dv.setInt8(this.position,value);
        this.position ++;
    }
    setInt16(value:number){
        this.dv.setInt16(this.position,value, this.littleEndian);
        this.position += 2;
    }
    setInt32(value:number){
        this.dv.setInt32(this.position,value, this.littleEndian);
        this.position += 4;
    }     
    
    setFloat32(value:number){
        this.dv.setFloat32(this.position,value, this.littleEndian);
        this.position += 4;
    }

    setFloat64(value:number){
        this.dv.setFloat32(this.position,value, this.littleEndian);
        this.position += 8;
    }    


    getUint8(){
        return this.dv.getUint8(this.position++);
    }
    getUint16(){
        let value = this.dv.getUint16(this.position, this.littleEndian);
        this.position += 2;
        return value;
    }
    getUint32(){
        let value = this.dv.getUint32(this.position, this.littleEndian);
        this.position += 4;
        return value;
    } 

    getInt8(){
        return this.dv.getInt8(this.position++);
    }
    getInt16(){
        let value = this.dv.getInt16(this.position, this.littleEndian);
        this.position += 2;
        return value;
    }
    getInt32(){
        let value = this.dv.getInt32(this.position, this.littleEndian);
        this.position += 4;
        return value;
    }


    getFloat32(){
        let value = this.dv.getFloat32(this.position, this.littleEndian);
        this.position += 4;
        return value;
    }

    getFloat64(){
        let value = this.dv.getFloat32(this.position, this.littleEndian);
        this.position += 8;
        return value;
    }
   
    setUTF(str:string){
        this.dv.setUint16(this.position, str.length, this.littleEndian); 
        this.position += 2;  
        //这个Uint16是表示字符串的字节大小，在写入字符串的时候一定要先写一个Uint16
       for(var i = 0; i < str.length; i++) {
           this.dv.setUint8(this.position++, str[i].charCodeAt(0));
       }  
    }

    getUTF():string{
        var len = this.dv.getInt16(this.position, this.littleEndian);
        this.position += 2;
        var str = "";
        for(var i = 0; i < len; i++) { 
             str = str + String.fromCharCode(this.dv.getUint8(this.position++));
        }
        return str;
    }

    byteArrayTest(){
        
        var str = "test!!" 
        let value = 4 + 2 + 4 + 2 + str.length;
        console.log(" value ",value);
        var byteArr = new ArrayBuffer(value);   
        //参数是ArrayBuffer的字节大小。
        var dv = new DataView(byteArr);  
         //DataView有三个参数，后两个可以缺省；每一个要是ArrayBuffer对象或SharedArrayBuffer对象 
         //下面的DataView的setUint*和getUint*方法自己去查阅。 
         dv.setUint32(0, 234, false);   
         dv.setUint16(4, 123, false);
         dv.setFloat32(6, 55.66, false); 
         dv.setUint16(10, str.length, false);   
         //这个Uint16是表示字符串的字节大小，在写入字符串的时候一定要先写一个Uint16
        for(var i = 0; i < str.length; i++) {
            dv.setUint8(12 + i, str[i].charCodeAt(0));
        }  
           var dataView = new DataView(byteArr);
           var int = dataView.getInt32(0, false);
           var short = dataView.getInt16(4, false);
           var float = dataView.getFloat32(6, false);
           var len = dataView.getInt16(10, false);
            var str2 = "";
            for(var i = 0; i < len; i++) { 
                 str2 = str2 + String.fromCharCode(dv.getUint8(12 + i));
            }
            console.log(int, short, float, len);
            console.log("str2 ",str2);
    }    
}
